﻿using Core.Info;
using Core.Log;
using Core.Utility.Cache;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{
    /// <summary>
    /// Json缓存助手类
    /// 文件缓存规则：data.section.data.value 存储到文件为base64后的字符串
    /// </summary>
    public static class JsonCacheHelper
    {
        /// <summary>
        /// 默认文件后缀名
        /// </summary>
        public const string DEFAULT_FILE_SUFFIX = ".cache.json";

        /// <summary>
        /// 应用JSON缓存名
        /// </summary>
        public const string APP_JSON_CACHE_FULL_FILE_NAME = $"app{DEFAULT_FILE_SUFFIX}";


        /// <summary>
        /// 控件JSON缓存名
        /// </summary>
        public const string CONTROL_JSON_CACHE_FULL_FILE_NAME = $"control{DEFAULT_FILE_SUFFIX}";


        /// <summary>
        /// 缓存目录：应用根目录/Cache/
        /// </summary>
        public static string CacheDirectory { get; private set; }


        /// <summary>
        /// 默认构造`
        /// </summary>
        static JsonCacheHelper()
        {
            CacheDirectory = Path.Combine(AppInfo.CacheDirectory);
            if (!Directory.Exists(CacheDirectory))
            {
                Directory.CreateDirectory(CacheDirectory);
            }
        }

        #region 读取
        /// <summary>
        /// 读取AppJson缓存
        /// </summary>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCache ReadAppJsonCache(string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return ReadJsonCacheByFielFullPath(fileFullPath);
        }

        /// <summary>
        /// 读取控件Json缓存
        /// </summary>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCache ReadControlJsonCache(string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            return ReadJsonCacheByFielFullPath(fileFullPath);
        }

        /// <summary>
        /// 读取Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCache ReadJsonCache(string fileName, string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return ReadJsonCacheByFielFullPath(fileFullPath);
        }

        /// <summary>
        /// 读取Json缓存,通过文件完整路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件全路径，包含文件所在的目录及扩展名</param>
        /// <returns></returns>
        public static JsonCache ReadJsonCacheByFielFullPath(string fileFullPath)
        {
            JsonCache? res = DefaultJsonCache();
            try
            {
                if (!File.Exists(fileFullPath))
                {
                    AppTrace.Logger.LogInformation($"读取JSON缓存文件不存，缓存路径：\r\n{fileFullPath}\r\n将使用默认值加载！");
                    FileHelper.WriteFileReturnBool(fileFullPath, JsonHelper.Serialize(DefaultJsonCache()));
                }
                string? fileJsonString = FileHelper.ReadFileToString(fileFullPath);
                res = JsonHelper.Deserialize<JsonCache>(fileJsonString);
                if (res != null)
                {
                    res = res?.JsonCacheValueConverter(JsonCacheValueOperation.Base64StringToString);
                }
            }
            catch (Exception ex)
            {
                AppTrace.Logger.LogError(ex, $"读取JSON缓存出错，缓存路径：\r\n{fileFullPath}\r\n这可能是因为缓存文件内容不合法,将使用默认值加载！");
            }
            if(res == null)
            {
                res = DefaultJsonCache();
            }
            return res;
        }
        #endregion 读取

        #region 保存
        /// <summary>
        /// 保存 App Json缓存
        /// </summary>
        /// <param name="jsonCache"></param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SaveAppJsonCache(this JsonCache jsonCache, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string message = "";
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return SaveJsonCacheByFielFullPath(jsonCache, fileFullPath, out message);
        }

        /// <summary>
        /// 保存 控件 Json缓存
        /// </summary>
        /// <param name="jsonCache"></param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SaveControlJsonCache(this JsonCache jsonCache, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string message = "";
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            return SaveJsonCacheByFielFullPath(jsonCache, fileFullPath, out message);
        }

        /// <summary>
        /// 保存Json缓存
        /// </summary>
        /// <param name="jsonCache"></param>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <returns></returns>
        public static bool SaveJsonCache(this JsonCache jsonCache, string fileName, string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            string message = "";
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return SaveJsonCacheByFielFullPath(jsonCache,fileFullPath,out message);
        }

        /// <summary>
        /// 保存Json缓存 通过文件完整路径
        /// </summary>
        /// <param name="jsonCache"></param>
        /// <param name="fileFullPath">缓存文件全路径，包含文件所在的目录及扩展名</param>
        /// <param name="message">保存的消息提示</param>
        /// <returns></returns>
        public static bool SaveJsonCacheByFielFullPath(this JsonCache jsonCache, string fileFullPath,out string message)
        {
            bool res = false;
            try
            {
                var saveJsonCache = jsonCache.DeepCopyByJson();
                saveJsonCache = saveJsonCache.JsonCacheValueConverter();
                res = FileHelper.WriteFileReturnBool(fileFullPath, JsonHelper.Serialize(saveJsonCache));
                message = "操作成功";
            }
            catch (Exception ex)
            {
                message = $"保存JSON缓存出错，缓存路径：\r\n{fileFullPath}\r\n";
                AppTrace.Logger.LogError(ex, message);
            }
            return res;
        }
        #endregion 保存

        #region 获取缓存 - App
        /// <summary>
        /// 获取 App Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static string? GetAppJsonCache(string section, string key, string defaultValue = "",string cacheAttachDirectory = "")
        {
            return GetAppJsonCache<string>(section, key, defaultValue, cacheAttachDirectory);
        }


        /// <summary>
        /// 获取 App Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static T? GetAppJsonCache<T>(string section, string key, T? defaultValue = default(T), string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheByFileFullPath<T>(fileFullPath, section, key, defaultValue);
        }

        /// <summary>
        /// 获取 App Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCacheSection GetAppJsonCacheSection(string section, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheSectionByFileFullPath(fileFullPath, section);
        }

        /// <summary>
        /// 获取 App Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static List<JsonCacheSectionItem>? GetAppJsonCacheSectionItems(string section, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheSectionItemsByFileFullPath(fileFullPath, section);
        }
        #endregion 获取缓存 - App

        #region 获取缓存 - 控件
        /// <summary>
        /// 获取 控件 Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static string? GetControlJsonCache(string section, string key, string defaultValue = "", string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory,cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheByFileFullPath(fileFullPath, section, key, defaultValue);
        }

        /// <summary>
        /// 获取 控件 Json缓存
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static TData? GetControlJsonCache<TData>(string section, string key, TData? defaultValue = default(TData), string cacheAttachDirectory = "")
            where TData :new()
        {
            TData? res = defaultValue;
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            var dataJsonString = GetJsonCacheByFileFullPath(fileFullPath, section, key, "");
            if(!string.IsNullOrEmpty(dataJsonString))
            {
                try
                {
                    res = JsonHelper.Deserialize<TData>(dataJsonString);
                }
                catch(Exception ex)
                {
                    AppTrace.Logger.LogError (ex, "获取 控件 Json缓存 反序列化失败");
                }
            }
            return res;
        }

        /// <summary>
        /// 获取 控件 Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCacheSection GetControlJsonCacheSection(string section, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheSectionByFileFullPath(fileFullPath, section);
        }

        /// <summary>
        /// 获取 控件 Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static List<JsonCacheSectionItem>? GetControlJsonCacheSectionItems(string section, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            return GetJsonCacheSectionItemsByFileFullPath(fileFullPath, section);
        }
        #endregion 获取缓存 - 控件

        #region 获取缓存
        /// <summary>
        /// 获取Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static string? GetJsonCache(string fileName, string section, string key, string defaultValue = "", string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            return GetJsonCache<string>(fileName, section, key, defaultValue, cacheAttachDirectory, fileSuffix);
        }

        /// <summary>
        /// 获取Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static T? GetJsonCache<T>(string fileName, string section, string key, T? defaultValue = default(T), string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return GetJsonCacheByFileFullPath<T>(fileFullPath,section,key,defaultValue);
        }

        /// <summary>
        /// 获取Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static JsonCacheSection GetJsonCacheSection(string fileName, string section, string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return GetJsonCacheSectionByFileFullPath(fileFullPath, section);
        }

        /// <summary>
        /// 获取Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static List<JsonCacheSectionItem> GetJsonCacheSectionItems(string fileName, string section, string cacheAttachDirectory = "", string fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return GetJsonCacheSectionItemsByFileFullPath(fileFullPath, section);
        }
        #endregion 获取缓存

        #region 获取缓存 - 通过文件全路径
        /// <summary>
        /// 获取Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <returns></returns>
        public static JsonCacheSection GetJsonCacheSectionByFileFullPath(string fileFullPath, string section)
        {
            JsonCacheSection res = new JsonCacheSection();
            if (File.Exists(fileFullPath) && !string.IsNullOrEmpty(section))
            {
                JsonCache jsonCache = ReadJsonCacheByFielFullPath(fileFullPath);
                if (jsonCache != null)
                {
                    var findCacheSection = jsonCache?.Data?.FirstOrDefault(p => p?.Section == section);
                    if (findCacheSection != null)
                    {
                        res = findCacheSection;
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// 获取Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <returns></returns>
        public static List<JsonCacheSectionItem> GetJsonCacheSectionItemsByFileFullPath(string fileFullPath, string section)
        {
            List<JsonCacheSectionItem> res = GetJsonCacheSectionByFileFullPath(fileFullPath, section)?.Item ?? new List<JsonCacheSectionItem>();
            if(res == null)
            {
                res = new List<JsonCacheSectionItem>();
            }
            return res;
        }

        /// <summary>
        /// 获取Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <returns></returns>
        public static string? GetJsonCacheByFileFullPath(string fileFullPath, string section, string key, string defaultValue = "")
        {
            return GetJsonCacheByFileFullPath<string>(fileFullPath, section, key, defaultValue);
        }


        /// <summary>
        /// 获取Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="defaultValue">获取缓存的默认值</param>
        /// <returns></returns>
        public static T? GetJsonCacheByFileFullPath<T>(string fileFullPath, string section, string key, T? defaultValue = default(T))
        {
            T? res = defaultValue;
            var jsonCacheSectionItems = GetJsonCacheSectionItemsByFileFullPath(fileFullPath, section);
            if (jsonCacheSectionItems?.Count() > 0)
            {
                var jsonCacheSectionItem = jsonCacheSectionItems?.FirstOrDefault(p => p.Key == key);
                if (jsonCacheSectionItem != null)
                {
                    string? content = jsonCacheSectionItem?.Content;
                    res = ValueTypeConvertHelper.ChangeType(content, defaultValue);
                }
            }
            return res;
        }
        #endregion 获取缓存 - 通过文件全路径

        #region 设置文件缓存 - App
        /// <summary>
        /// 设置AppJson缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="value">设置缓存的值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SetAppJsonCache(string section, string key, string? value, string? cacheAttachDirectory = "")
        {
            return SetAppJsonCache<string>(section, key, value, cacheAttachDirectory);
        }


        /// <summary>
        /// 设置AppJson缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="value">设置缓存的值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SetAppJsonCache<T>(string section, string key, T? value, string? cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, APP_JSON_CACHE_FULL_FILE_NAME);
            return SetJsonCacheByFileFullPath(fileFullPath, section, key, value);
        }
        #endregion 设置文件缓存 - App


        #region 设置文件缓存 - 控件
        /// <summary>
        /// 设置 控件 Json缓存
        /// </summary>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="value">设置缓存的值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SetControlJsonCache(string section, string key, string? value, string cacheAttachDirectory = "")
        {
            if(value == null)
            {
                value = "";
            }
            return SetControlJsonCache<string>(section, key, value, cacheAttachDirectory); 
        }

        /// <summary>
        /// 设置 控件 Json缓存
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="value">设置缓存的值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SetControlJsonCache<TValue>(string section, string key, TValue? value, string cacheAttachDirectory = "")
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, CONTROL_JSON_CACHE_FULL_FILE_NAME);
            string? jsonValue = "";
            if (value is string valueStr)
            {
                jsonValue = valueStr;
            }
            else
            {
                jsonValue = JsonHelper.Serialize(value);
            }
            return SetJsonCacheByFileFullPath(fileFullPath, section, key, jsonValue);
        }
        #endregion 设置文件缓存 - 控件

        /// <summary>
        /// 设置Json缓存
        /// </summary>
        /// <param name="fileName">缓存文件名，不含文件目录及扩展名</param>
        /// <param name="fileSuffix">缓存文件扩展名，默认使用 <see cref="DEFAULT_FILE_SUFFIX"/></param>
        /// <param name="section">缓存节，不区分大小写</param>
        /// <param name="key">缓存节的key，不区分大小写</param>
        /// <param name="value">设置缓存的值</param>
        /// <param name="cacheAttachDirectory">缓存附加目录，通常用于不同账号、租户间的缓存目录区分</param>
        /// <returns></returns>
        public static bool SetJsonCache(string fileName, string section, string key, string? value, string? cacheAttachDirectory = "", string? fileSuffix = DEFAULT_FILE_SUFFIX)
        {
            if (string.IsNullOrEmpty(cacheAttachDirectory))
            {
                cacheAttachDirectory = "";
            }
            string fileFullPath = Path.Combine(CacheDirectory, cacheAttachDirectory, $"{fileName}{fileSuffix}");
            return SetJsonCacheByFileFullPath(fileFullPath, section, key, value);
        }

        /// <summary>
        /// 设置Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写,不能为空，否则抛出异常</param>
        /// <param name="value">设置缓存的值</param>
        /// <returns></returns>
        public static bool SetJsonCacheSectionItemsByFileFullPath(string fileFullPath, string section, List<JsonCacheSectionItem>? value = null)
        {
            if (string.IsNullOrEmpty(section))
            {
                throw new ArgumentNullException(nameof(section), "参数不能为空");
            }
            if(value == null)
            {
                value = new List<JsonCacheSectionItem>();
            }
            bool res = false;
            JsonCache setJsonCache = ReadJsonCacheByFielFullPath(fileFullPath);
            var findCacheSection = setJsonCache?.Data?.FirstOrDefault(p => p?.Section == section);
            if (findCacheSection != null)
            {
                var findCacheSectionIndex = setJsonCache?.Data?.IndexOf(findCacheSection);
                findCacheSection.Item = value;
                if (setJsonCache?.Data != null && findCacheSectionIndex != null)
                {
                    setJsonCache.Data[findCacheSectionIndex.GetValueOrDefault()] = findCacheSection;
                }
            }
            else
            {
                findCacheSection = new JsonCacheSection()
                {
                    Section = section,
                    Item = value
                };
                if (setJsonCache == null)
                {
                    setJsonCache = new JsonCache();
                }
                if (setJsonCache?.Data == null)
                {
#pragma warning disable CS8602 // 解引用可能出现空引用。
                    setJsonCache.Data = new List<JsonCacheSection?>()
                    {
                        findCacheSection
                    };
#pragma warning restore CS8602 // 解引用可能出现空引用。
                }
                else
                {
                    setJsonCache.Data.Add(findCacheSection);
                }
            }
#pragma warning disable CS8602 // 解引用可能出现空引用。
            setJsonCache.UpdatedTime = AppTime.Now;
            setJsonCache.Revision = Guid.NewGuid().ToString();
#pragma warning restore CS8602 // 解引用可能出现空引用。
            string message = "";
            res = setJsonCache.SaveJsonCacheByFielFullPath(fileFullPath, out message);
            return res;
        }

        /// <summary>
        /// 设置Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写,不能为空，否则抛出异常</param>
        /// <param name="key">缓存节的key，不区分大小写,不能为空，否则抛出异常</param>
        /// <param name="value">设置缓存的值</param>
        /// <returns></returns>
        public static bool SetJsonCacheByFileFullPath(string fileFullPath, string section, string key, string? value = "")
        {
            return SetJsonCacheByFileFullPath<string>(fileFullPath, section, key, value);
        }

        /// <summary>
        /// 设置Json缓存，通过文件全路径
        /// </summary>
        /// <param name="fileFullPath">缓存文件名，全路径，包含文件所在的目录及扩展名</param>
        /// <param name="section">缓存节，不区分大小写,不能为空，否则抛出异常</param>
        /// <param name="key">缓存节的key，不区分大小写,不能为空，否则抛出异常</param>
        /// <param name="value">设置缓存的值</param>
        /// <returns></returns>
        public static bool SetJsonCacheByFileFullPath<T>(string fileFullPath, string section, string key, T? value = default(T))
        {
            if (string.IsNullOrEmpty(section))
            {
                throw new ArgumentNullException(nameof(section), "参数不能为空");
            }
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key), "参数不能为空");
            }
            bool res = false;
            JsonCache setJsonCache = ReadJsonCacheByFielFullPath(fileFullPath);
            if (setJsonCache == null)
            {
                setJsonCache = new JsonCache();
            }
            var findCacheSection = setJsonCache?.Data?.FirstOrDefault(p => p?.Section == section);
            if (findCacheSection != null)
            {
                var findCacheSectionIndex = setJsonCache?.Data?.IndexOf(findCacheSection);
                var findData = findCacheSection?.Item?.FirstOrDefault(p => key == p.Key);
                if (findData != null)
                {
                    var findDataIndex = findCacheSection?.Item?.IndexOf(findData);
                    findData.Content = value?.ToString();
                    if (findCacheSection?.Item != null && findDataIndex != null)
                    {
                        findCacheSection.Item[findDataIndex.GetValueOrDefault()] = findData;
                    }
                }
                else
                {
                    findData = new JsonCacheSectionItem()
                    {
                        Key = key,
                        Content = value?.ToString(),
                    };
                    findCacheSection?.Item?.Add(findData);
                }
                if (setJsonCache?.Data != null && findCacheSectionIndex != null)
                {
                    setJsonCache.Data[findCacheSectionIndex.GetValueOrDefault(0)] = findCacheSection;
                }
            }
            else
            {
                findCacheSection = new JsonCacheSection()
                {
                    Section = section,
                    Item = new List<JsonCacheSectionItem>()
                    {
                        new JsonCacheSectionItem()
                        {
                            Key = key,
                            Content = value?.ToString(),
                        }
                    }
                };
                if (setJsonCache != null && setJsonCache.Data == null)
                {
                    setJsonCache.Data = new List<JsonCacheSection?>()
                    {
                        findCacheSection
                    };
                }
                else
                {
                    setJsonCache?.Data?.Add(findCacheSection);
                }

            }
#pragma warning disable CS8602 // 解引用可能出现空引用。
            setJsonCache.UpdatedTime = AppTime.Now;
            setJsonCache.Revision = Guid.NewGuid().ToString();
#pragma warning restore CS8602 // 解引用可能出现空引用。
            string message = "";
            res = setJsonCache.SaveJsonCacheByFielFullPath(fileFullPath, out message);
            return res;
        }

        /// <summary>
        /// Json缓存值转换
        /// </summary>
        /// <param name="jsonCache"></param>
        /// <param name="jsonCacheValueOperation">Json缓存值操作，参照<see cref="JsonCacheValueOperation"/></param>
        /// <returns></returns>
        public static JsonCache JsonCacheValueConverter(this JsonCache jsonCache, JsonCacheValueOperation jsonCacheValueOperation = JsonCacheValueOperation.StringToBase64String)
        {
            JsonCache res = jsonCache.DeepCopyByJson();
            if (res != null)
            {
                if (res?.Data?.Count > 0)
                {
                    var jsonCacheDataList = res.Data;
                    #region 遍历Json缓存的数据节点
                    for (int iCacheData = 0; iCacheData < jsonCacheDataList.Count; iCacheData++)
                    {
                        var jsonCacheDataItem = jsonCacheDataList[iCacheData];
                        if (jsonCacheDataItem?.Item?.Count > 0)
                        {
                            #region 遍历Json缓存数据节点的Section
                            for (int iSection = 0; iSection < jsonCacheDataItem.Item.Count; iSection++)
                            {
                                var jsonCacheDataSection = jsonCacheDataItem.Item[iSection];
                                if (jsonCacheValueOperation == JsonCacheValueOperation.Base64StringToString)
                                {
                                    jsonCacheDataSection.Content = ValueTypeConvertHelper.Base64StringToUtf8String(jsonCacheDataSection.Content);
                                }
                                else if (jsonCacheValueOperation == JsonCacheValueOperation.StringToBase64String)
                                {
                                    jsonCacheDataSection.Content = ValueTypeConvertHelper.ToUtf8Base64String(jsonCacheDataSection.Content);
                                }
                                jsonCacheDataItem.Item[iSection] = jsonCacheDataSection;
                            }
                            #endregion 遍历Json缓存数据节点的Section 
                        }
                    }
                    #endregion 遍历Json缓存的数据节点 
                }
            }
            return res ?? new JsonCache();
        }

        /// <summary>
        /// 默认Json缓存
        /// </summary>
        /// <returns></returns>
        private static JsonCache DefaultJsonCache()
        {
            return new JsonCache()
            {
                CreatedTime = AppTime.Now,
                UpdatedTime = AppTime.Now,
                Revision = Guid.NewGuid().ToString(),
                Data = new List<JsonCacheSection?>(),
            };
        }
    }
}
